﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Sealight.API.Framework;
using NHibernate;

namespace Sealight.Data
{
    public class NHibernateRepository<T> : RepositoryBase<T>
    {
        public NHibernateRepository()
        {
            if (UnitOfWork.Current == null)
                throw new ArgumentNullException("Current UnitOfWork is NULL.  Please start UnitOfWork before instantiate repository intance.");
           

        }

        /// <summary>
        /// Save or Update T
        /// </summary>
        /// <param name="entity"></param>
        public override void Save(T entity)
        {
            if (entity == null)
                throw new ArgumentNullException();
            try
            {
                UnitOfWork.CurrentSession.Save(entity);
            }
            catch (ADOException ex)
            {
                //log4net

                //must close session on error
                //if (UnitOfWork.CurrentSession != null && UnitOfWork.CurrentSession.IsOpen)
                //    UnitOfWork.CurrentSession.Close();
                //rethrow the exception
                throw;
            }
        }

        /// <summary>
        /// Save or Update T
        /// </summary>
        /// <param name="entity"></param>
        public override void SaveOrUpdate(T entity)
        {
            if (entity == null)
                throw new ArgumentNullException();
            try
            {
                UnitOfWork.CurrentSession.SaveOrUpdate(entity);
            }
            catch (ADOException ex)
            {
                //log4net

                //must close session on error
                //if (UnitOfWork.CurrentSession != null && UnitOfWork.CurrentSession.IsOpen)
                //    UnitOfWork.CurrentSession.Close();
                //rethrow the exception
                throw;
            }
        }

        public override void Update(T entity)
        {
            if (entity == null)
                throw new ArgumentNullException();
            try
            {
                UnitOfWork.CurrentSession.Update(entity);
            }
            catch (ADOException ex)
            {
                //log4net

                //must close session on error
                //if (UnitOfWork.CurrentSession != null && UnitOfWork.CurrentSession.IsOpen)
                //    UnitOfWork.CurrentSession.Close();
                //rethrow the exception
                throw;
            }
        }

        /// <summary>
        /// Return entity based on T
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public override T GetById(Guid id)
        {
            T entity;
            try
            {
                entity = UnitOfWork.CurrentSession.Get<T>(id);
            }
            catch (ADOException ex)
            {
                //log4net

                //must close session on error
                //if (UnitOfWork.CurrentSession != null && UnitOfWork.CurrentSession.IsOpen)
                //    UnitOfWork.CurrentSession.Close();
                //rethrow the exception
                throw;
            }
            return entity;
        }

        /// <summary>
        /// return all member
        /// </summary>
        /// <returns></returns>
        public override IList<T> GetAll()
        {
            //return ((NHibernateUnitOfWork)UnitOfWork.Current).Session.CreateCriteria(typeof(T)).List<T>();
            return UnitOfWork.CurrentSession.CreateCriteria(typeof(T)).List<T>();
        }

        public override void Delete(T entity)
        {
            try
            {
                UnitOfWork.CurrentSession.Delete(entity);
            }
            catch (ADOException ex)
            {
                //log4net

                //must close session on error
                ////if (UnitOfWork.CurrentSession != null && UnitOfWork.CurrentSession.IsOpen)
                ////    UnitOfWork.CurrentSession.Close();
                //rethrow the exception
                throw;
            }
        }

        
    }
}
